home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / x2ftp / msdos / mxcode / ariawave / aria.c < prev    next >
C/C++ Source or Header  |  1994-12-04  |  9KB  |  311 lines

  1. /* ARIA.C v0.02 */
  2.  
  3. #include <go32.h>
  4. #include <dpmi.h>
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <dos.h>
  8. #include <pc.h>
  9. #include "aria.h"
  10.  
  11. /* Declare global Aria parameters and set them at default values */
  12. volatile unsigned int aria_baseport   = 0x290;
  13. volatile unsigned int aria_interrupt  = 0x72;
  14. volatile unsigned int aria_irq        = 10;
  15. volatile unsigned int aria_packetsize = 512;
  16. volatile unsigned int aria_samplesize = 0;
  17. volatile unsigned int aria_dma        = 5;
  18.  
  19. unsigned short *wave_ptr;
  20. volatile long buffer_ptr=0;
  21.  
  22. _go32_dpmi_seginfo oldirq_rm, rm_si, oldirq_pm, pm_si;
  23. _go32_dpmi_registers rm_regs;
  24.  
  25.  
  26. void aria_putmem (int address, int word)
  27. {
  28.   outportw (aria_baseport+4, address);
  29.   outportw (aria_baseport+6, word);
  30. }
  31.  
  32.  
  33. int aria_getmem (int address)
  34. {
  35.   int word;
  36.   outportw (aria_baseport+4, address);
  37.   word=inportw (aria_baseport+6);
  38.   return word;
  39. }
  40.  
  41.  
  42. /* Send a command to the Aria DSP */
  43. void aria_sendcmd (unsigned command)
  44. {
  45.   unsigned i=65535;                           /* Set time out counter */
  46.   while (i--)
  47.   {
  48.     if (!(inportw(aria_baseport+2) & 0x8000)) /* Wait until the Aria DSP is */
  49.                                               /* ready to receive a command */
  50.     {
  51.       outportw (aria_baseport, command);      /* Send the command */
  52.       return;
  53.     }
  54.   }
  55.   return;                                     /* Time out! */
  56. }
  57.  
  58.  
  59. /* Set up for one of the three playback modes. Don't issue this command    */
  60. /* while PCM audio channels or synthesizer operators are still active.     */
  61. /* Mode 0: 4 mono or 2 stereo PCM audio channels  ; no synthesis operators */
  62. /* Mode 1: 2 mono or 1 stereo PCM audio channel(s); 20 synthesis operators */
  63. /* Mode 2: 2 mono or 1 stereo PCM audio channel(s); 32 synthesis operators */
  64. /* The default mode is 2. Mode 1 is meant for simultaneous use with other  */
  65. /* DSP applications such as reverb processing, QSOUND, or Aria Listener.   */
  66. void aria_set_playback_mode(unsigned mode)
  67. {
  68.   disable();
  69.   aria_sendcmd (0x06);
  70.   aria_sendcmd (mode);
  71.   aria_sendcmd (0xffff);
  72.   enable();
  73. }
  74.  
  75.  
  76. void aria_start_playback()
  77. {
  78.   disable();
  79.   aria_sendcmd (0x11);
  80.   aria_sendcmd (0x00);
  81.   aria_sendcmd (0xffff);
  82.   enable();
  83. }
  84.  
  85.  
  86. void aria_stop_playback()
  87. {
  88.   disable();
  89.   aria_sendcmd (0x12);
  90.   aria_sendcmd (0x00);
  91.   aria_sendcmd (0xffff);
  92.   enable();
  93.  
  94. }
  95.  
  96.  
  97. /* Reading the parameter format as a hex code the following table applies: */
  98. /*   format: 00xy        x = sample rate      y = data format              */
  99. /*                       0 : 11.025 kHz       0 : 8-bit mono (default)     */
  100. /*                       1 : 22.050 kHz       1 : 8-bit stereo             */
  101. /*                       2 : 44.100 kHz       2 : 16-bit mono              */
  102. /*                                            3 : 16-bit stereo            */
  103. /*                                            4 : ADPCM compressed mono    */
  104. /*                                            5 : ADPCM compressed stereo  */
  105. void aria_set_audio_format(unsigned format)
  106. {
  107.   /* If playing at 44 kHz is requested we have to set some parameters */
  108.   if (format>=32)
  109.   {
  110.     aria_set_playback_mode (0);
  111.     disable();
  112.     outportw (aria_baseport+2,0x8a);
  113.     enable();
  114.   }
  115.  
  116.   disable();
  117.   aria_sendcmd (0x03);
  118.   aria_sendcmd (format);
  119.   aria_sendcmd (0xffff);
  120.   enable();
  121. }
  122.  
  123.  
  124. /* As Aria operates at default in SB emulation mode, */
  125. /* here we set up for Aria native mode               */
  126. void aria_init()
  127. {
  128.   int ready=0;
  129.  
  130.   outportw (aria_baseport+2,0xc8);          /* Aria init */
  131.   aria_putmem (0x6102,0);                   /* Clear task init flag */
  132.  
  133.   /* Aria DSP Init */
  134.   disable();
  135.   aria_sendcmd (0x00);
  136.   aria_sendcmd (0x00);
  137.   aria_sendcmd (0x00);
  138.   aria_sendcmd (0x00);
  139.   aria_sendcmd (0xffff);
  140.   enable();
  141.  
  142.   /* Wait for Aria DSP init to complete */
  143.   while (ready != 1)
  144.   {
  145.     outportw (aria_baseport+4, 0x6102);
  146.     ready = inportw (aria_baseport+6);
  147.   }
  148.  
  149.   outportw (aria_baseport+2,0xca);          /* Complete Aria init */
  150. }
  151.  
  152.  
  153. void aria_irqhandler()
  154. {
  155.   volatile unsigned short address;
  156.   volatile long i;
  157.  
  158.   /* Check interrupt type and exit handler if not generated by Aria */
  159.   if (inportw(aria_baseport) != 1)
  160.   {
  161.     outportb (0xa0,0x20);   /* secondary controller EOI */
  162.     outportb (0x20,0x20);   /* primary controller EOI   */
  163.     enable();
  164.     return;
  165.   }
  166.  
  167.   /* Play aria_packetsize words from the sample buffer */
  168.   address=0x8000;
  169.   address-=aria_packetsize;
  170.   address-=aria_packetsize;
  171.   address+=aria_getmem (0x6100);
  172.   outportw(aria_baseport+4,address);
  173.   for (i=0;i<aria_packetsize;i++)
  174.     outportw(aria_baseport+6,*(wave_ptr+buffer_ptr+i));
  175.   aria_sendcmd (0x10);
  176.   aria_sendcmd (0xffff);
  177.  
  178.   buffer_ptr+=aria_packetsize;
  179.  
  180.   /* If at end of sample buffer do a wrap around */
  181.   if (buffer_ptr > ((aria_samplesize-aria_packetsize)/2))
  182.     buffer_ptr=0;
  183.  
  184.   /* Reset interrupt controllers by sending EOIs (EOI=End Of Interrupt) */
  185.   outportb (0xa0,0x20);   /* secondary controller EOI */
  186.   outportb (0x20,0x20);   /* primary controller EOI   */
  187.   enable();
  188. }
  189.  
  190.  
  191. void aria_install_interrupt_handler ()
  192. {
  193.   int ret;
  194.   disable();
  195.  
  196.   /* Install real mode interrupt handler */
  197.   rm_si.pm_offset = (int) aria_irqhandler;
  198.   ret = _go32_dpmi_allocate_real_mode_callback_iret(&rm_si, &rm_regs);
  199.   if (ret != 0)
  200.   {
  201.     printf ("cannot allocate real mode callback, error=%04x\n",ret);
  202.     exit(1);
  203.   }
  204.   _go32_dpmi_get_real_mode_interrupt_vector(aria_interrupt, &oldirq_rm);
  205.   _go32_dpmi_set_real_mode_interrupt_vector(aria_interrupt, &rm_si);
  206.  
  207.   /* Install protected mode interrupt handler */
  208.   pm_si.pm_offset = (int) aria_irqhandler;
  209.   ret = _go32_dpmi_allocate_iret_wrapper(&pm_si);
  210.   if (ret != 0)
  211.   {
  212.     printf ("cannot allocate protected mode wrapper, error=%04x\n",ret);
  213.     exit(1);
  214.   }
  215.   pm_si.pm_selector = _go32_my_cs();
  216.   _go32_dpmi_get_protected_mode_interrupt_vector (aria_interrupt, &oldirq_pm);
  217.   _go32_dpmi_set_protected_mode_interrupt_vector(aria_interrupt, &pm_si);
  218.  
  219.   /* Enable interrupts via Aria's IRQ */
  220.   outportw (0xA1,inportb(0xA1) & ~(1<<(aria_irq-8)));
  221.   enable();
  222. }
  223.  
  224.  
  225. void aria_release_interrupt_handler ()
  226. {
  227.   disable();
  228.  
  229.   /* Disable interrupts via Aria's IRQ */
  230.   outportw (0xA1,inportb(0xA1) | (1<<(aria_irq-8)));
  231.  
  232.   /* Remove our real mode interrupt handler */
  233.   _go32_dpmi_set_real_mode_interrupt_vector(aria_interrupt, &oldirq_rm);
  234.   if (rm_si.size != -1)
  235.     _go32_dpmi_free_real_mode_callback(&rm_si);
  236.   rm_si.size = -1;
  237.  
  238.   /* Remove our protected mode interrupt handler */
  239.   if (pm_si.size != -1)
  240.     _go32_dpmi_free_iret_wrapper (&pm_si);
  241.   pm_si.size = -1;
  242.   _go32_dpmi_set_protected_mode_interrupt_vector(aria_interrupt,&oldirq_pm);
  243.  
  244.   enable();
  245. }
  246.  
  247.  
  248. /* Resets Aria to defaults */
  249. void aria_reset (unsigned format)
  250. {
  251.   /* If Aria was set up for playing at 44 kHz we have to reset this to 22 */
  252.   if (format>=32)
  253.   {
  254.     aria_set_playback_mode (2);
  255.     disable();
  256.     outportw (aria_baseport+2,0xca);
  257.     enable();
  258.   }
  259.  
  260.   /* As Aria operates in SB emulation mode at default we have to switch */
  261.   /* to SB emulation mode before exiting our application */
  262.   outportw (aria_baseport+2,0x40);
  263. }
  264.  
  265.  
  266. /* Initializes global variables aria_baseport, aria_irq and aria_dma with */
  267. /* settings found in the ARIA environment parameter                       */
  268. void aria_getparms ()
  269. {
  270.     char *t, *aria;
  271.  
  272.     t = getenv("ARIA");
  273.     if (!t)
  274.         return;
  275.  
  276.     aria = strdup(t);                /* Get a copy */
  277.  
  278.     t = strtok(aria, " \t");         /* Parse the ARIA parameter */
  279.     while (t) {
  280.         switch (t[0]) {
  281.             case 'A':
  282.             case 'a':
  283.                 /* I/O address */
  284.                 sscanf(t + 1, "%x", &aria_baseport);
  285.                 break;
  286.             case 'I':
  287.             case 'i':
  288.                 /* IRQ */
  289.                 aria_irq = atoi(t + 1);
  290.                 break;
  291.             case 'D':
  292.             case 'd':
  293.                 /* DMA channel */
  294.                 aria_dma = atoi(t + 1);
  295.                 break;
  296.             case 'T':
  297.             case 't':
  298.                 /* Version */
  299.                 break;
  300.  
  301.             default:
  302.                 printf("Unknown ARIA option %c\n",t[0]);
  303.                 break;
  304.         }
  305.         t = strtok(NULL," \t");
  306.     }
  307.  
  308.     free(aria);
  309.     return;
  310. }
  311.